package com.excesys.exsecs.alarm.service.impl;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.excesys.exsecs.access.entity.AccessDeviceInfo;
import com.excesys.exsecs.access.service.AccessDeviceInfoService;
import com.excesys.exsecs.admin.api.entity.SysLog;
import com.excesys.exsecs.admin.api.entity.SysUser;
import com.excesys.exsecs.admin.service.SysUserService;
import com.excesys.exsecs.alarm.entity.AlarmRecord;
import com.excesys.exsecs.alarm.entity.AlarmTypeConf;
import com.excesys.exsecs.alarm.mapper.AlarmRecordMapper;
import com.excesys.exsecs.alarm.service.AlarmRecordService;
import com.excesys.exsecs.alarm.service.AlarmTypeConfService;
import com.excesys.exsecs.alarm.util.DateUtil;
import com.excesys.exsecs.common.core.util.R;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 告警记录列表
 *
 * @author lxc
 * @date 2024-10-14 16:41:24
 */
@Service
@RequiredArgsConstructor
public class AlarmRecordServiceImpl extends ServiceImpl<AlarmRecordMapper, AlarmRecord> implements AlarmRecordService {

    private final SysUserService sysUserService;
    private final AlarmTypeConfService alarmTypeConfService;
    private final AccessDeviceInfoService accessDeviceInfoService;

    @Override
    public Page queryPage(Page page, AlarmRecord alarmRecord) {
        LambdaQueryWrapper<AlarmRecord> wrapper = Wrappers.<AlarmRecord>lambdaQuery()
                .eq(StrUtil.isNotBlank(alarmRecord.getAlarmTypeCode()), AlarmRecord::getAlarmTypeCode, alarmRecord.getAlarmTypeCode())
                .eq(ObjectUtils.isNotEmpty(alarmRecord.getAlarmLevel()), AlarmRecord::getAlarmLevel, alarmRecord.getAlarmLevel())
                .eq(StrUtil.isNotEmpty(alarmRecord.getAlarmStatus()), AlarmRecord::getAlarmStatus, alarmRecord.getAlarmStatus())
                .eq(StrUtil.isNotEmpty(alarmRecord.getIsRead()), AlarmRecord::getIsRead, alarmRecord.getIsRead())
                .eq(StrUtil.isNotEmpty(alarmRecord.getOrderStatus()), AlarmRecord::getOrderStatus, alarmRecord.getOrderStatus())
                .orderByDesc(AlarmRecord::getHappenTime);
        if (ArrayUtil.isNotEmpty(alarmRecord.getQueryTime())){
            wrapper.ge(AlarmRecord::getCreateTime, alarmRecord.getQueryTime()[0]).le(AlarmRecord::getCreateTime, alarmRecord.getQueryTime()[1]);
        }
        Page<AlarmRecord> page1 = this.page(page,wrapper);
        if (ObjectUtils.isNotEmpty(page1) && CollectionUtils.isNotEmpty(page1.getRecords())) {
            page1.getRecords().forEach(it ->{
                if (StringUtils.isNotBlank(it.getSender())){
                    String[] userId = it.getSender().split(",");
                    it.setSenderList(userId);
                    List<SysUser> users = sysUserService.list(Wrappers.<SysUser>lambdaQuery().in(SysUser::getUserId, userId));
                    if (CollectionUtils.isNotEmpty(users)) {
                        it.setSenderName(users.stream().map(SysUser::getName).collect(Collectors.joining(",")));
                    }
                }

                if (StringUtils.isNotBlank(it.getAlarmTypeCode())){
                    AlarmTypeConf conf = alarmTypeConfService.getOne(Wrappers.<AlarmTypeConf>lambdaQuery().eq(AlarmTypeConf::getTypeCode, it.getAlarmTypeCode()));
                    if (ObjectUtils.isNotEmpty(conf)) {
                        it.setAlarmTypeName(conf.getTypeName());
                    }
                }
                if (StringUtils.isNotBlank(it.getUnitNo())){
                    AccessDeviceInfo Info = accessDeviceInfoService.getOne(Wrappers.<AccessDeviceInfo>lambdaQuery().eq(AccessDeviceInfo::getUnitNo, it.getUnitNo()));
                    if (ObjectUtils.isNotEmpty(Info)) {
                        it.setUnitName(Info.getDeviceName());
                    }
                }
            });
        }
        return page1;
    }

    @Override
    public AlarmRecord getRecordById(Long id) {
        //查看详情，将未读改成已读
        AlarmRecord record = this.getById(id);
        if (ObjectUtils.isNotEmpty(record) && "0".equals(record.getIsRead())) {
            this.lambdaUpdate().set(AlarmRecord::getIsRead, '1').eq(AlarmRecord::getId, id).update(new AlarmRecord());
        }
        if (StringUtils.isNotBlank(record.getSender())){
            String[] userId = record.getSender().split(",");
            record.setSenderList(userId);
            List<SysUser> users = sysUserService.list(Wrappers.<SysUser>lambdaQuery().in(SysUser::getUserId, userId));
            if (CollectionUtils.isNotEmpty(users)) {
                record.setSenderName(users.stream().map(SysUser::getName).collect(Collectors.joining(",")));
            }
        }
        if (StringUtils.isNotBlank(record.getAlarmTypeCode())){
            AlarmTypeConf conf = alarmTypeConfService.getOne(Wrappers.<AlarmTypeConf>lambdaQuery().eq(AlarmTypeConf::getTypeCode, record.getAlarmTypeCode()));
            if (ObjectUtils.isNotEmpty(conf)) {
                record.setAlarmTypeName(conf.getTypeName());
            }
        }
        return record;
    }

    @Override
    public boolean saveRecord(AlarmRecord alarmRecord) {
        alarmRecord.setTimePartition(Integer.parseInt(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMM"))));
        return this.save(alarmRecord);
    }



    @Override
    public boolean updateRecordById(AlarmRecord alarmRecord) {
        return this.updateById(alarmRecord);
    }

    @Override
    public List<Map> getEchartsByTimeRange(AlarmRecord alarmRecord) {
        List<Map> result = new ArrayList<>();
        //获取时间范围中的天集合
        LocalDateTime[] queryTime = alarmRecord.getQueryTime();
        LocalDate startDate = queryTime[0].toLocalDate();
        LocalDate endDate = queryTime[1].toLocalDate();
        List<LocalDate> localDates = DateUtil.generateDatesInRange(startDate, endDate);
        List<Map<String, Object>> list = this.baseMapper.getEchartsByTimeRange(startDate, endDate);
        if (CollectionUtils.isEmpty(list)) {
            for (LocalDate localDate : localDates) {
                Map map = new HashMap();
                map.put("timeDay", localDate);
                map.put("count", 0);
                result.add(map);
            }
            return result;
        }
        Map<String,Object> tranfMap = new HashMap();
        list.forEach(data ->{
            tranfMap.put(data.get("timeDay").toString(), data.get("count"));
        });
        // 使用Stream API处理listA，创建新的Map列表
        result = localDates.stream()
                .map(date -> {
                    // 从mapB中获取值，如果没有则默认为"0"
                    Object value = tranfMap.get(date.toString());
                    if (ObjectUtils.isEmpty(value)){
                        value = 0;
                    }
                    // 创建新的Map，并添加key1和key2
                    Map<String, Object> resultMap = new HashMap<>();
                    resultMap.put("timeDay", date);
                    resultMap.put("count", value);
                    return resultMap;
                })
                .collect(Collectors.toList());
        return result;
    }

    @Override
    public List<Map> getAlarmTypeProp(AlarmRecord alarmRecord) {
        //获取时间范围
        LocalDateTime[] queryTime = alarmRecord.getQueryTime();
        LocalDate startDate = queryTime[0].toLocalDate();
        LocalDate endDate = queryTime[1].toLocalDate();
        //AlarmType的groupby统计数量
        return this.baseMapper.getAlarmTypeProp(startDate, endDate);
    }

    @Override
    public List<Map> getLevelStatis(AlarmRecord alarmRecord) {
        //获取时间范围
        LocalDateTime[] queryTime = alarmRecord.getQueryTime();
        LocalDate startDate = queryTime[0].toLocalDate();
        LocalDate endDate = queryTime[1].toLocalDate();
        //AlarmType的groupby统计数量
        return this.baseMapper.getLevelStatis(startDate, endDate);
    }

    @Override
    public List<Map> getStatusStatis(AlarmRecord alarmRecord) {
        //获取时间范围
        LocalDateTime[] queryTime = alarmRecord.getQueryTime();
        LocalDate startDate = queryTime[0].toLocalDate();
        LocalDate endDate = queryTime[1].toLocalDate();
        //AlarmType的groupby统计数量
        return this.baseMapper.getStatusStatis(startDate, endDate);
    }
}